
#include <BStyle>
#include <BScript>
#include <BViewer>
#include <BScene>
#include <BPicker>
#include <BReadWrite>
#include <BApplication>
#include <BRoundHandler>

#include "ClassViewer.h"

ClassViewer::ClassViewer() : BClass("Viewer")
{
	this->insertVariant("BViewer", "viewer");

	this->insertMethod("Viewer()", &ClassViewer::create);

	this->insertMethod("void setTitle(string)", &ClassViewer::setTitle);
	this->insertMethod("void setBackground(const Color&);", &ClassViewer::setBackground);

	this->insertMethod("void setPos(int, int)", &ClassViewer::setPos);
	this->insertMethod("void setSize(int, int)", &ClassViewer::setSize);
	this->insertMethod("void show()", &ClassViewer::show);

	this->insertMethod("bool empty() const", &ClassViewer::empty);
	this->insertMethod("bool load(const string&);", &ClassViewer::load);

	this->insertMethod("bool setProperty(const string& name, const auto& value)", &ClassViewer::setProperty);
	this->insertMethod("auto property(const string& name) const", &ClassViewer::property);

	this->insertMethod("void setScene(Scene* scene);", &ClassViewer::setScene);
	this->insertMethod("Scene* scene() const;", &ClassViewer::scene);

	this->insertMethod("void setCamera(Camera* camera);", &ClassViewer::setCamera);
	this->insertMethod("Camera* camera();", &ClassViewer::camera);
	this->insertMethod("const Camera* camera() const;", &ClassViewer::camera_const);

	this->insertMethod("void setHandler(Handler* handler);", &ClassViewer::setHandler);
	this->insertMethod("Handler* handler();", &ClassViewer::handler);
	this->insertMethod("const Handler* handler() const;", &ClassViewer::handler_const);

	this->insertMethod("void setPicker(Picker* picker);", &ClassViewer::setPicker);
	this->insertMethod("Picker* picker();", &ClassViewer::picker);
	this->insertMethod("const Picker* picker() const;", &ClassViewer::picker_const);

	this->insertMethod("real unit(real dist) const;", &ClassViewer::unit_dist);
	this->insertMethod("real unit(const Vector& point) const;", &ClassViewer::unit_point);

	this->insertMethod("Vector vertex(int x, int y, real d) const;", &ClassViewer::vertex_x_y_d);
	this->insertMethod("Line line(int x, int y) const;", &ClassViewer::vertex_point_d);

	this->insertMethod("Vector vertex(const Point& point, real d) const;", &ClassViewer::line_x_y);
	this->insertMethod("Line line(const Point& point) const;", &ClassViewer::line_point);

	this->insertMethod("Point point(const Vector vector);", &ClassViewer::point);

	this->insertMethod("PickHit* pick(int x, int y) const;", &ClassViewer::pick_x_y);
	this->insertMethod("PickHit* pick(const Point& point) const;", &ClassViewer::pick_point);

}

BClass* ClassViewer::clone() const
{
	ClassViewer* cls = new ClassViewer();
	cls->copy(this);
	return cls;
}

void ClassViewer::create(int argc, BValue* argv)
{

}

void ClassViewer::setTitle(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		const BString& title = argv[1];
		viewer->setTitle(title);
	}
}
void ClassViewer::setBackground(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		const BColor& color = argv[1];
		BCamera* camera = viewer->camera();
		camera->setColor(color);
	}
}

void ClassViewer::setPos(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		int x = argv[1];
		int y = argv[2];
		viewer->setPos(x, y);
	}
}
void ClassViewer::setSize(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		int width = argv[1];
		int height = argv[2];
		viewer->setSize(width, height);
	}
}
void ClassViewer::show(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		viewer->show();
	}
}

void ClassViewer::empty(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		argv[0] = viewer->scene() == 0;
	}
}
void ClassViewer::load(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		BString path = BApplication::currentPath();
		const BString& fileName = argv[1];
		BScene* scene = ReadFile<BScene>(fileName);
		viewer->setScene(scene);

		const BSpace& space = scene->space();
		BCamera* camera = viewer->camera();
		camera->setPosition(space.center());
		camera->setCenter(space.center() + BVector(space.width(), 0, 0));
		camera->setNear(1);
		camera->setFar(space.width() / 5);

		BRoundHandler* handler = (BRoundHandler*)viewer->handler();
		handler->focus(space);

	}
}

void ClassViewer::setProperty(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		const BString& name = argv[1];
		const BValue& value = argv[2].refer();
		argv[0] = viewer->setProperty(name, value);
	}
}
void ClassViewer::property(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		const BString& name = argv[1];
		argv[0] = viewer->property(name);
	}
}

void ClassViewer::setScene(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		BScene* scene = argv[1];
		viewer->setScene(scene);
	}
}
void ClassViewer::scene(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		argv[0] = viewer->scene();
	}
}

void ClassViewer::setCamera(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		BCamera* camera = argv[1];
		viewer->setCamera(camera);
	}
}
void ClassViewer::camera(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		argv[0] = viewer->camera();
	}
}
void ClassViewer::camera_const(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		argv[0] = viewer->camera();
	}
}

void ClassViewer::setHandler(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		BHandler* handler = argv[1];
		viewer->setHandler(handler);
	}
}
void ClassViewer::handler(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		argv[0] = viewer->handler();
	}
}
void ClassViewer::handler_const(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		argv[0] = viewer->handler();
	}
}

void ClassViewer::setPicker(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		BPicker* picker = argv[1];
		viewer->setPicker(picker);
	}
}
void ClassViewer::picker(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		argv[0] = viewer->picker();
	}
}
void ClassViewer::picker_const(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		argv[0] = viewer->picker();
	}
}

void ClassViewer::unit_dist(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		BReal dist = argv[1];
		argv[0] = viewer->unit(dist);
	}
}
void ClassViewer::unit_point(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		const BVector& point = argv[1];
		argv[0] = viewer->unit(point);
	}
}

void ClassViewer::vertex_x_y_d(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		int x = argv[1];
		int y = argv[2];
		BReal d = argv[3];
		viewer->vertex(x, y, d);
	}
}
void ClassViewer::vertex_point_d(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		const BPoint& point = argv[1];
		BReal d = argv[2];
		viewer->vertex(point, d);
	}
}

void ClassViewer::line_x_y(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		int x = argv[1];
		int y = argv[2];
		viewer->line(x, y);
	}
}
void ClassViewer::line_point(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		const BPoint& point = argv[1];
		viewer->line(point);
	}
}

void ClassViewer::point(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		const BVector vector = argv[1];
		viewer->point(vector);
	}
}

void ClassViewer::pick_x_y(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		int x = argv[1];
		int y = argv[2];
		viewer->pick(x, y);
	}
}
void ClassViewer::pick_point(int argc, BValue* argv)
{
	if (BViewer* viewer = this->value("viewer"))
	{
		const BPoint& point = argv[1];
		viewer->pick(point);
	}
}
